#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Run Deep Hook and Capture Encryption
运行深度Hook并捕获加密过程
"""

import frida
import sys
import time
import requests
import io
import json

# Fix encoding
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

print("\n" + "="*80)
print("Deep Hook - Shumei Encryption Analysis")
print("="*80 + "\n")

# ============================================================================
# Step 1: Connect to device and attach to process
# ============================================================================

print("[Step 1] Connecting to device...")
try:
    device = frida.get_usb_device()
    print(f"[OK] Device: {device.name}\n")
except Exception as e:
    print(f"[ERROR] Failed to connect: {e}")
    sys.exit(1)

print("[Step 2] Attaching to process (PID 2586)...")
try:
    session = device.attach(2586)
    print(f"[OK] Attached to PID 2586\n")
except Exception as e:
    print(f"[ERROR] Failed to attach: {e}")
    sys.exit(1)

# ============================================================================
# Step 2: Load hook script
# ============================================================================

print("[Step 3] Loading hook script...")
try:
    with open("deep_hook.js", "r", encoding="utf-8") as f:
        hook_code = f.read()
    
    script = session.create_script(hook_code)
    
    # Message handler
    def on_message(message, data):
        try:
            if message['type'] == 'send':
                payload = message['payload']
                if isinstance(payload, str):
                    print(payload)
                else:
                    print(json.dumps(payload, indent=2, ensure_ascii=False))
            elif message['type'] == 'error':
                print(f"\n[FRIDA ERROR]")
                print(f"Stack: {message.get('stack', 'No stack trace')}")
                print(f"Description: {message.get('description', 'No description')}\n")
        except Exception as e:
            print(f"[Message Handler Error] {e}")
    
    script.on('message', on_message)
    script.load()
    print("[OK] Hook script loaded\n")
    
except Exception as e:
    print(f"[ERROR] Failed to load script: {e}")
    session.detach()
    sys.exit(1)

# ============================================================================
# Step 3: Wait for hooks to settle
# ============================================================================

print("[Step 4] Waiting for hooks to initialize (3 seconds)...")
time.sleep(3)

# ============================================================================
# Step 4: Call API to trigger encryption
# ============================================================================

print("\n" + "="*80)
print("[Step 5] Calling API to trigger encryption...")
print("="*80 + "\n")

api_url = "http://120.27.155.222:9999/api/message/send-test"

try:
    response = requests.get(api_url, timeout=15)
    print(f"\n[API Response]")
    print(f"Status: {response.status_code}")
    print(f"Content-Type: {response.headers.get('Content-Type')}")
    
    if response.status_code == 200:
        try:
            data = response.json()
            print(f"\nResponse JSON:")
            print(json.dumps(data, indent=2, ensure_ascii=False))
            
            if 'dev' in data:
                dev_value = data['dev']
                print(f"\n[IMPORTANT] dev field (Base64):")
                print(f"Length: {len(dev_value)}")
                print(f"Value: {dev_value[:100]}...")
                
        except Exception as e:
            print(f"Response text: {response.text[:200]}")
    else:
        print(f"Error response: {response.text}")
        
except Exception as e:
    print(f"[ERROR] API call failed: {e}")

# ============================================================================
# Step 5: Wait for hook output
# ============================================================================

print("\n" + "="*80)
print("[Step 6] Waiting for hook output (15 seconds)...")
print("="*80 + "\n")

time.sleep(15)

# ============================================================================
# Step 6: Call API again to see pattern
# ============================================================================

print("\n" + "="*80)
print("[Step 7] Calling API second time...")
print("="*80 + "\n")

try:
    response = requests.get(api_url, timeout=15)
    if response.status_code == 200:
        data = response.json()
        if 'dev' in data:
            print(f"dev (2nd call): {data['dev'][:100]}...")
except Exception as e:
    print(f"[ERROR] {e}")

print("\n[Step 8] Waiting for hook output (15 seconds)...")
time.sleep(15)

# ============================================================================
# Step 7: Keep listening
# ============================================================================

print("\n" + "="*80)
print("[READY] Hook is active. Press Ctrl+C to exit...")
print("="*80)
print("\nYou can now:")
print("  1. Call the API manually from another terminal")
print("  2. Trigger the app functionality")
print("  3. Observe the hook output in real-time\n")

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    print("\n\n[+] Stopping...")
    try:
        script.unload()
        session.detach()
    except:
        pass
    print("[OK] Exited cleanly\n")


